package geektime.concurrent.part2.executors;

import io.netty.util.concurrent.DefaultThreadFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

/**
 * 让多个线程在同时执行一种任务，当其中一个线程得到返回结果后，其他的线程就直接停止
 */
public class ForkingClusterDemo {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(10));

        // 让多个线程在同时执行同一种任务，当其中一个线程执行完毕后，其他的线程就直接停止
//        Future<?> submit1 = threadPoolExecutor.submit(new MyThread());
//        Future<?> submit2 = threadPoolExecutor.submit(new MyThread());
//        Future<?> submit3 = threadPoolExecutor.submit(new MyThread());
//        while (true) {
//            if (submit1.isDone() || submit2.isDone() || submit3.isDone()) {
//                threadPoolExecutor.shutdownNow();
//                break;
//            }
//        }

        // 让多个线程同时执行同一种任务，当其中一个线程获取到任务结果后，其他的线程就直接停止
        Future<String> submit1 = threadPoolExecutor.submit(() -> getResult());
        Future<String> submit2 = threadPoolExecutor.submit(() -> getResult());
        Future<String> submit3 = threadPoolExecutor.submit(() -> getResult());
        List<Future<String>> futureList = Arrays.asList(submit1, submit2, submit3);
        String result;
        while (true) {
            for (Future<String> future : futureList) {
                if (future.isDone()) {
                    result = future.get();
                    System.out.println("Get the result=" + result);
                    threadPoolExecutor.shutdownNow();
                    return;
                }
            }
        }
    }

    private static String getResult() {
        String threadName = Thread.currentThread().getName();
        int sleepTime = new Random().nextInt(20) + 1;
        System.out.println(threadName + " needs " + sleepTime + " seconds to execute the task.");
        try {
            TimeUnit.SECONDS.sleep(sleepTime);
            System.out.println(threadName + " had finished the task.");
            return "result";
        } catch (InterruptedException e) {
            System.out.println(threadName + " was shutdown due to other thread had finished the task.");
            e.printStackTrace();
        }
        return null;
    }

    public static class MyThread extends Thread {
        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + " is executing the task...");
            // 模拟需要执行的任务
            try {
                int sleepTime = new Random().nextInt(20) + 1;
                System.out.println(threadName + " needs " + sleepTime + " seconds to execute the task.");
                TimeUnit.SECONDS.sleep(sleepTime);
                System.out.println(threadName + " had finished the task.");
            } catch (InterruptedException e) {
                System.out.println(threadName + " was shutdown due to other thread had finished the task.");
                e.printStackTrace();
            }
        }
    }

    public static class MyFutureTask extends FutureTask {

        public MyFutureTask(Callable callable) {
            super(callable);
        }
    }
}
